﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;
using System.IO.Compression;

namespace ZDT.Http
{
    public class Url
    {
        public static CookieCollection ParseCookie(string cookies)
        {
            var cl = new CookieCollection();
            foreach (string sc in cookies.Split(';'))
            {
                string ss = sc.Trim();
                if (ss.IndexOf("&") > 0)
                {
                    foreach (string s1 in ss.Split('&'))
                    {
                        string s2 = s1.Trim();
                        string s4 = s2.Substring(s2.IndexOf("=") + 1, s2.Length - s2.IndexOf("=") - 1);

                        cl.Add(new Cookie(s2.Split('=')[0].Trim(), s4, "/"));
                    }
                }
                else
                {
                    string s3 = sc.Trim();
                    cl.Add(new Cookie(s3.Split('=')[0].Trim(), s3.Split('=')[1].Trim(), "/"));
                }
            }
            return cl;
        }
        public static void AddCookie(HttpWebRequest request, string cookies)
        {
            var cookieC = request.CookieContainer;
            if (cookieC == null)
            {
                cookieC = request.CookieContainer = new CookieContainer();
            }
            cookieC.Add(ParseCookie(cookies));
        }
        /// <summary>
        /// 根据采集url地址以及编码方式获得网页源代码
        /// </summary>
        /// <param name="strUrl">信息采集地址 eg:www.sina.com</param>
        /// <param name="strEncoding">编码方式 eg:gb2312,utf-8 etc</param>
        /// <param name="coiokies">coikies</param>
        /// <returns>网页源代码字符串</returns>
        public static string GetSource(string strUrl, string strEncoding, string cookies = "", RequestHandle requestHandle = null, ResponseHandle responseHandle = null)
        {
            string lsResult;
            try
            {
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(strUrl);
                if (!string.IsNullOrEmpty(cookies))
                {
                    AddCookie(req, cookies);
                }
                if (requestHandle != null)
                {
                    requestHandle(req);
                }
                HttpWebResponse rep = (HttpWebResponse)req.GetResponse();
                if (string.IsNullOrEmpty(strEncoding))
                {
                    strEncoding = rep.CharacterSet;
                }
                var stream=rep.GetResponseStream();
                StreamReader sr = new StreamReader(stream, Encoding.GetEncoding(strEncoding));
                lsResult = sr.ReadToEnd();
                sr.Close();
                sr.Dispose();
                if (responseHandle != null)
                {
                    responseHandle(rep);
                }
            }
            catch (Exception ex)
            {
                lsResult = "";
                Console.WriteLine(ex.Message);
            }
            return lsResult;
        }
        public delegate void RequestHandle(HttpWebRequest response);
        public delegate void ResponseHandle(HttpWebResponse response);
        public static string GetSource(string url, GlobalParas.WebCode webCode, string cookies,  RequestHandle requestHandle = null, ResponseHandle responseHandle = null)
        {
            return GetSource(url, cookies, webCode, string.Empty, string.Empty, false, requestHandle, responseHandle);
        }
        /// <summary>
        /// 获取指定网址源码
        /// </summary>
        /// <param name="url">网址</param>
        /// <param name="cookies">网页cookies</param>
        /// <param name="webCode">网页编码</param>
        /// <param name="startPos">获取网页源码的起始位置</param>
        /// <param name="endPos">获取网页源码的终止位置</param>
        /// <param name="IsCutnr">是否截取回车换行符，默认为false，截取</param>
        /// <returns></returns>
        public static string GetSource(string url, string cookies, GlobalParas.WebCode webCode, string startPos = "", string endPos = "", bool IsCutnr = false, RequestHandle requestHandle = null, ResponseHandle responseHandle = null)
        {
            //判断网页编码
            Encoding wCode;
            string PostPara = "";
            HttpWebRequest wReq;

            if (Regex.IsMatch(url, @"<POST>.*</POST>", RegexOptions.IgnoreCase))
            {
                wReq = (HttpWebRequest)WebRequest.Create(@url.Substring(0, url.IndexOf("<POST>")));
            }
            else
            {
                wReq = (HttpWebRequest)WebRequest.Create(@url);
            }


            wReq.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.0; .NET CLR 1.1.4322; .NET CLR 2.0.50215;)";
            //wReq.Headers.Add("Accept-Language", "zh-cn,en-us;q=0.5");
            //wReq.Headers.Add("Accept-Encoding", "gzip, deflate");
            //wReq.SendChunked = true;
            //wReq.TransferEncoding = "utf-8";

            Match a = Regex.Match(url, @"(http://).[^/]*[?=/]", RegexOptions.IgnoreCase);
            string url1 = a.Groups[0].Value.ToString();
            wReq.Referer = url1;

            //判断是否有cookie
            if (cookies != "")
            {
                CookieContainer CookieCon = new CookieContainer();
                CookieCollection cl = ParseCookie(cookies);
                CookieCon.Add(new Uri(url), cl);
                wReq.CookieContainer = CookieCon;
            }

            //判断是否含有POST参数
            if (Regex.IsMatch(url, @"(?<=<POST>)[\S\s]*(?=</POST>)", RegexOptions.IgnoreCase))
            {

                Match s = Regex.Match(url, @"(?<=<POST>).*(?=</POST>)", RegexOptions.IgnoreCase);
                PostPara = s.Groups[0].Value.ToString();
                byte[] pPara = Encoding.ASCII.GetBytes(PostPara);

                wReq.ContentType = "application/x-www-form-urlencoded";
                wReq.ContentLength = pPara.Length;

                wReq.Method = "POST";

                System.IO.Stream reqStream = wReq.GetRequestStream();
                reqStream.Write(pPara, 0, pPara.Length);
                reqStream.Close();
                reqStream.Dispose();

            }
            else
            {
                wReq.Method = "GET";

            }

            //设置页面超时时间为12秒
            wReq.Timeout = 12000;
            if (requestHandle != null)
            {
                requestHandle(wReq);
            }
            HttpWebResponse wResp = (HttpWebResponse)wReq.GetResponse();

            System.IO.Stream respStream = wResp.GetResponseStream();
            string strWebData = "";

            switch (webCode)
            {
                case GlobalParas.WebCode.auto:
                    try
                    {
                        wCode = Encoding.Default;
                        string cType = wResp.ContentType.ToLower();
                        Match charSetMatch = Regex.Match(cType, "(?<=charset=)([^<]*)*", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                        string webCharSet = charSetMatch.ToString();
                        wCode = System.Text.Encoding.GetEncoding(webCharSet);
                    }
                    catch
                    {
                        wCode = Encoding.Default;
                    }

                    break;
                case GlobalParas.WebCode.gb2312:
                    wCode = Encoding.GetEncoding("gb2312");
                    break;
                case GlobalParas.WebCode.gbk:
                    wCode = Encoding.GetEncoding("gbk");
                    break;
                case GlobalParas.WebCode.utf8:
                    wCode = Encoding.UTF8;
                    break;
                default:
                    wCode = Encoding.UTF8;
                    break;
            }


            if (wResp.ContentEncoding == "gzip")
            {
                GZipStream myGZip = new GZipStream(respStream, CompressionMode.Decompress);
                System.IO.StreamReader reader;
                reader = new System.IO.StreamReader(myGZip, wCode);
                strWebData = reader.ReadToEnd();
                reader.Close();
                reader.Dispose();
            }
            else
            {
                System.IO.StreamReader reader;
                reader = new System.IO.StreamReader(respStream, wCode);
                strWebData = reader.ReadToEnd();
                reader.Close();
                reader.Dispose();
            }

            if (responseHandle != null)
            {
                responseHandle(wResp);
            }

            //去除回车换行符号
            if (IsCutnr == true)
            {
                strWebData = Regex.Replace(strWebData, "([\\r\\n])[\\s]+", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                strWebData = Regex.Replace(strWebData, "\\n", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                strWebData.Replace("\\r\\n", "");
            }

            //获取此页面的编码格式,并对源码进行一次判断,无论用户是否指定了网页代码
            //Match charSetMatch = Regex.Match(strWebData, "<meta([^<]*)charset=([^<]*)\"", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            //string webCharSet = charSetMatch.Groups[2].Value;
            //string charSet = webCharSet;

            //if (charSet != null && charSet != "" && Encoding.GetEncoding(charSet) != wCode)
            //{
            //    byte[] myDataBuffer;

            //    myDataBuffer = System.Text.Encoding.GetEncoding(charSet).GetBytes(strWebData);
            //    strWebData = Encoding.GetEncoding(charSet).GetString(myDataBuffer);

            //}

            //按照截取网页的起始标志和终止标志进行截取
            //如果起始或终止截取标识有一个为空，则不进行截取
            if (startPos != "" && endPos != "")
            {
                string Splitstr = "(" + startPos + ").*?(" + endPos + ")";

                Match aa = Regex.Match(strWebData, Splitstr);
                strWebData = aa.Groups[0].ToString();
            }
            return strWebData;

        }
        private static int DEF_PACKET_LENGTH=1024;
        //下载文件，是一个单线程的方法，适用于小文件下载，仅支持http方式
        public static GlobalParas.DownloadResult DownloadFile(string url, string cookies, string path)
        {
            HttpWebRequest wReq = null;
            HttpWebResponse wRep = null;
            FileStream SaveFileStream = null;

            int startingPoint = 0;

            try
            {
                //For using untrusted SSL Certificates

                wReq = (HttpWebRequest)HttpWebRequest.Create(url);
                wReq.AddRange(startingPoint);
                 //判断是否有cookie
                if (cookies != "")
                {
                    CookieContainer CookieCon = new CookieContainer();
                    CookieCollection cl = ParseCookie(cookies);
                    CookieCon.Add(new Uri(url), cl);
                    wReq.CookieContainer = CookieCon;
                }
                wRep = (HttpWebResponse)wReq.GetResponse();
                Stream responseSteam = wRep.GetResponseStream();

                if (startingPoint == 0)
                {
                    SaveFileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
                }
                else
                {
                    SaveFileStream = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
                }

                int bytesSize;
                long fileSize = wRep.ContentLength;
                byte[] downloadBuffer = new byte[DEF_PACKET_LENGTH];

                while ((bytesSize = responseSteam.Read(downloadBuffer, 0, downloadBuffer.Length)) > 0)
                {
                    SaveFileStream.Write(downloadBuffer, 0, bytesSize);
                }

                SaveFileStream.Close();
                SaveFileStream.Dispose();

                wRep.Close();

                return GlobalParas.DownloadResult.Succeed;

            }
            catch (System.Exception)
            {
                return GlobalParas.DownloadResult.Err;
            }
        }

        public static void UploadFile(string url, string cookies, string path)
        {


        }

        //获取采集内容的纯文本
        public static string GetTxt(string instr)
        {
            string m_outstr;
            m_outstr = instr.Clone() as string;
            //m_outstr = new System.Text.RegularExpressions.Regex(@"(?m)<script[^>]*>(\w|\W)*?</script[^>]*>", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(m_outstr, "");
            //m_outstr = new System.Text.RegularExpressions.Regex(@"(?m)<style[^>]*>(\w|\W)*?</style[^>]*>", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(m_outstr, "");
            //m_outstr = new System.Text.RegularExpressions.Regex(@"(?m)<select[^>]*>(\w|\W)*?</select[^>]*>", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(m_outstr, "");
            ////if (!withLink)
            ////    m_outstr = new Regex(@"(?m)<a[^>]*>(\w|\W)*?</a[^>]*>", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(m_outstr, "");
            System.Text.RegularExpressions.Regex objReg = new System.Text.RegularExpressions.Regex("(<[^>]+?>)|&nbsp;", RegexOptions.Multiline | RegexOptions.IgnoreCase);
            m_outstr = objReg.Replace(m_outstr, "");
            System.Text.RegularExpressions.Regex objReg2 = new System.Text.RegularExpressions.Regex("(\\s)+", RegexOptions.Multiline | RegexOptions.IgnoreCase);
            m_outstr = objReg2.Replace(m_outstr, " ");
            return m_outstr;
        }
    }
}
